package projekt.zaliczeniowy.tkunit.runner;

import projekt.zaliczeniowy.tkunit.runner.TestOrderStrategy.Strategy;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import projekt.zaliczeniowy.tkunit.test.Test;
import projekt.zaliczeniowy.tkunit.test.results.TestResult;

/**
 *
 * @author Admin
 */
public class TestRunner extends Observable implements Runnable {

    final Strategy strategy;
    //final Observer endOfTestsObserver;
    final List<TestResult> results;
    final List<Test> testsToRun;
    
    /**
     *  @return 
     */
    List<TestResult> getResults(){
        return this.results;
    }
    
    /**
     * @return 
     */
    List<Test> getTests(){
        return this.testsToRun;
    }

    TestRunner(Strategy strategy, Observer observer) {
        this.strategy = strategy;
        //this.endOfTestsObserver = observer;
        super.addObserver(observer);
        this.results = new LinkedList<TestResult>();
        this.testsToRun = new LinkedList<Test>();
    }
    
    public void cleanTestsToRun(){
        this.testsToRun.clear();
    }

    public void addTestsToRun(Test test) {
        this.testsToRun.add(test);
    }
    /*
    public void addTestToRun(Class<? extends Test> test) throws InstantiationException, IllegalAccessException {
        this.testsToRun.add(test.newInstance());
    }*/

    /**
     * wywołaj żeby zmienić obserwatora
     */
    /*
    @Override
    public void addObserver(Observer o) {
        super.deleteObservers();//we want only one observer
        super.addObserver(o);
    }
    */
    
    /**
     * wywołaj żeby poinformować obserwatora o końcu testów
     */
    private void notifyAboutTheEndOfTests() {
        super.setChanged();
        super.notifyObservers(results);
    }

    /**
     * zapuść testy - tu uzywamy wzorca strategia
     */
    private void checkOutTheTests() {
        Iterable<Test> iterableTestBox = new Iterable<Test>() {
            public Iterator<Test> iterator() {
                return strategy.getTestOrder(testsToRun);
            }
        };
        for(Test t : iterableTestBox){
            results.add(t.test());
        }
    }
    
    public void run(){
        checkOutTheTests();
        notifyAboutTheEndOfTests();
    }
}
